package net.dl.ss.dao.ibatis;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import com.ibatis.sqlmap.client.SqlMapClient;

public abstract class CommonDaoIbatis {
	    private SqlMapClient client;

	    public SqlMapClient getClient() {
	        return client;
	    }

	    public void setClient(SqlMapClient client) {
	        this.client = client;
	    }

	    protected abstract String getTypeAlias();

	    /**
	     * Ibatis implementation of common interface purposed to save entity if its identifier equals null
	     *
	     * @param entity entity object which will be made persistent
	     * @return same entity populated with newly created identifier
	     */
	    public <T> T saveEntity(final T entity) {
	        //((Persistable) entity).setId(nextId());
	        try {
	            getClient().startTransaction();
	            try {
	                getClient().insert(getTypeAlias()+".saveEntity", entity);
	                getClient().commitTransaction();
	            } finally {
	                getClient().endTransaction();
	            }
	        } catch(SQLException e) {
	            throw new RuntimeException(e);
	        }
	        return entity;
	    }

	    /**
	     * Ibatis implementation of common interface purposed to populate instantiated entity by its identifier
	     *
	     * @param object entity object which will be populated from persistent storage
	     * @param id identifier of persisted object
	     * @return loaded object with populated attributes
	     */
	    @SuppressWarnings("unchecked")
	    public <T> T load(T object, Serializable id) {
	        return (T) get(object.getClass(), id);
	    }

	    /**
	     * Ibatis implementation of common interface purposed to instantiate entity given identifier for selection
	     *
	     * @param c class description of persisted object
	     * @param id identifier value of persisted object
	     * @return newly instantiated entity
	     */
	    @SuppressWarnings("unchecked")
	    public <T> T get(Class<T> c, Serializable id) {
	        try {
	            return (T) IbatisUtil.queryObject(getClient(), getTypeAlias()+".get", id);
	        } catch(SQLException e) {
	            throw new RuntimeException(e);
	        }
	    }

	    /**
	     * Ibatis implementation of common interface  purposed to update entity if its identifier doesn't equal null
	     *
	     * @param entity object which will be synchronized with database
	     */
	    public void updateEntity(Object entity) {
	        try {
	            getClient().startTransaction();
	            try {
	                //int updatedRows = 
	            	getClient().update(getTypeAlias()+".updateEntity", entity);
	                getClient().commitTransaction();
	                //return updatedRows > 0;
	            } finally {
	                getClient().endTransaction();
	            }
	        } catch(SQLException e) {
	            throw new RuntimeException(e);
	        }
	    }

	    /**
	     * Ibatis implementation of common interface purposed to delete entity if its identifier doesn't equal null.
	     * But entity still stay transient and could be reused for different purposes
	     *
	     * @param entity object which will be deleted and made transient
	     */
	    public void deleteEntity(Object entity) {
	           deleteEntityById(((Persistable) entity).getId());
	    }

	    /**
	     * Ibatis implememtation of common interface purposed to delete row from database by identifier.
	     *
	     * @param id value of persistent object identifier
	     */
	    public void deleteEntityById(Long id) {
	        try {
	            getClient().startTransaction();
	            try {
	                getClient().delete(getTypeAlias()+".deleteEntity", id);
	                getClient().commitTransaction();
	            } finally {
	                getClient().endTransaction();
	            }
	        } catch(SQLException e) {
	            throw new RuntimeException(e);
	        }
	    }

	    /**
	     * Ibatis implementation of common interface to retrieve all entities from specific table or set of tables.
	     * Should be carefully and rarely used!!!
	     *
	     * @param c class of objects wich will be retrieved
	     * @return the list of entities
	     */
	    @SuppressWarnings("unchecked")
	    public <T> List<T> list(Class<T> c) {
	        try {
	            return (List) IbatisUtil.queryList(getClient(), getTypeAlias()+".list");
	        } catch(SQLException e) {
	            throw new RuntimeException(e);
	        }
	    }

	    /**
	     * @return the next id for entity
	     */
	   /* private long nextId() {
	        long ret= -1;
	        try {
	            ret = (Long)IbatisUtil.queryObject(getClient(), getTypeAlias()+".nextId");
	        } catch(SQLException e) {
	            throw new RuntimeException(e);
	        }
	        return ret;
	    }*/
	
}
